package org.groupg.practice;

import io.github.resilience4j.bulkhead.Bulkhead;           // 舱壁隔离（信号量）
import io.github.resilience4j.bulkhead.BulkheadFullException;
import io.github.resilience4j.bulkhead.ThreadPoolBulkhead; // 线程池舱壁隔离
import io.github.resilience4j.circuitbreaker.CallNotPermittedException;
import io.github.resilience4j.circuitbreaker.CircuitBreaker; // 熔断器
import io.github.resilience4j.decorators.Decorators;        // 装饰器工具
import io.github.resilience4j.retry.Retry;                 // 重试机制
import io.github.resilience4j.timelimiter.TimeLimiter;      // 超时控制
import java.time.Duration;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeoutException;
import java.util.function.Supplier;
import static java.util.Arrays.asList;

public class Main {
    public static void main(String[] args) {
        // ================== 1. 创建弹性组件 ================== //
        // 熔断器：当失败率达到阈值时自动断开请求
        CircuitBreaker circuitBreaker = CircuitBreaker.ofDefaults("backendService");

        // 重试器：默认配置（3次重试，500ms间隔）
        Retry retry = Retry.ofDefaults("backendService");

        // 信号量舱壁：限制并发调用数量
        Bulkhead bulkhead = Bulkhead.ofDefaults("backendService");

        // ================== 2. 准备后端服务调用 ================== //
        BackendService backendService = new BackendService();
        String param1 = "param1";
        String param2 = "param2";

        // 创建服务调用函数式接口
        Supplier<String> supplier = () -> backendService.doSomething(param1, param2);

        // ================== 3. 同步弹性装饰（组合模式） ================== //
        Supplier<String> decoratedSupplier = Decorators.ofSupplier(supplier)
                .withCircuitBreaker(circuitBreaker)  // 添加熔断
                .withBulkhead(bulkhead)              // 添加并发限制
                .withRetry(retry)                    // 添加自动重试
                .decorate();                         // 构建装饰链

        // ================== 4. 单独使用熔断器示例 ================== //
        String result = circuitBreaker.executeSupplier(backendService::doSomething);

        // ================== 5. 异步弹性调用（线程池隔离） ================== //
        // 线程池舱壁：使用独立线程池隔离资源
        ThreadPoolBulkhead threadPoolBulkhead = ThreadPoolBulkhead.ofDefaults("backendService");

        // 定时线程池（用于超时控制）
        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(3);

        // 超时控制器：设置1秒超时
        TimeLimiter timeLimiter = TimeLimiter.of(Duration.ofSeconds(1));

        CompletableFuture<String> future = Decorators.ofSupplier(supplier)
                .withThreadPoolBulkhead(threadPoolBulkhead)  // 线程池隔离
                .withTimeLimiter(timeLimiter, scheduledExecutorService) // 超时控制
                .withCircuitBreaker(circuitBreaker)           // 熔断保护
                // 降级处理（超时/熔断打开/舱壁满时返回预设值）
                .withFallback(asList(
                        TimeoutException.class,
                        CallNotPermittedException.class,
                        BulkheadFullException.class),
                    throwable -> "Hello from Recovery")
                .get().toCompletableFuture();  // 转换为CompletableFuture
    }
}
